import { useDirectoryPicker } from 'shared/hooks/useDirectoryPicker'
import { type CollectionOfWorks } from 'shared/types/works'
import tpl from '../assets/single-download.html?raw'
import { showMessage } from './message'
import { DouyinExtensionTool } from './element'



export function initializeSingleDownload(collectionOfWorks: CollectionOfWorks) {
  const { getRootHandle, showRootPicker, writeToLocal, existChild } = useDirectoryPicker({
    database: 'single_download',
    rootPickerOptions: {
      id: 'single_download',
      mode: 'readwrite',
    },
  })

  let cache: {
    worksId: string | null
    elem: HTMLLIElement | null
  } = {
    worksId: null,
    elem: null,
  }

  const toolElem = new DouyinExtensionTool(tpl, {
    download() {
      cache.worksId && executeDownload(cache.worksId)
    },
  })

  function updateHostStyle() {
    const rect = cache.elem?.getBoundingClientRect()
    if (rect) {
      toolElem.updateHostStyle({
        transform: `translate(${rect.left}px, ${rect.top}px)`,
        width: `${rect.width}px`,
      })
    }
  }

  function mount(worksId: string | null, elem: HTMLLIElement | null) {
    if (cache.elem === elem) return
    cache = { worksId, elem }

    if (elem) {
      toolElem.hidden = false
      updateHostStyle()
    } else {
      toolElem.hidden = true
    }
  }

  const regexp = /^\/video\/(\d+)$/

  function matchWorksId(anchor: HTMLAnchorElement): string | null {
    const href = anchor.getAttribute('href')
    if (href) {
      const [matched, worksId] = href.match(regexp) ?? []
      if (matched === href && worksId in collectionOfWorks.works) {
        return worksId
      }
    }
    return null
  }

  async function executeDownload(worksId: string) {
    try {
      const worksTarget = collectionOfWorks.works[worksId]
      if (!worksTarget)
        return showMessage({
          type: 'warn',
          message: '未找到该视频的下载资源',
        })

      const { title, video } = worksTarget
      const isExist = await existChild('file', ({ name }) => name === title)
      if (isExist)
        return showMessage({
          type: 'warn',
          message: `${title} 已在本地存在`,
        })

      const response = await fetch(video.at(-1)!)
      if (response.status !== 200)
        return showMessage({
          type: 'error',
          message: `${title} 资源获取失败`,
        })

      await showRootPicker()

      const blob = await response.blob()
      await writeToLocal({ blob, name: title, directory: getRootHandle()! })
      showMessage({ type: 'success', message: `${title} 已下载` })
    } catch (error: any) {
      showMessage({
        type: 'error',
        message: error?.message,
      })
    }
  }

  function analyzeElementPath(path: Element[]) {
    let worksId: string | null = null,
      elem: HTMLLIElement | null = null

    for (let i = 0; i < path.length; i++) {
      const el = path[i]
      if (el === toolElem) return
      if (el.nodeName === 'A') {
        worksId = matchWorksId(path[i] as HTMLAnchorElement)
      } else if (worksId && el.nodeName === 'LI') {
        elem = el as HTMLLIElement
        break
      }
    }

    mount(worksId, elem)
  }

  function initialize() {
    window.addEventListener('mousemove', (e) => {
      const path = e.composedPath() as Element[]
      analyzeElementPath(path)
    })

    window.addEventListener('scroll', () => {
      mount(null, null)
    })
  }

  function heartbeat() {
    if (collectionOfWorks.sid) {
      const [_, prefix, sid] = location.pathname.split('/')
      if (prefix === 'user' && collectionOfWorks.sid === sid) {
        return initialize()
      }
    }
    requestAnimationFrame(heartbeat)
  }

  heartbeat()
}
